﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using Csla;
using Csla.Core;
using Hardcodet.Wpf.GenericTreeView;
using OpenExpressApp.MetaModel;
using OpenExpressApp.Module.WPF;
using OpenExpressApp.Module.WPF.Editors.TreeColumn;
using Ricciolo.Controls;
using OpenExpressApp.Module.WPF.Controls;
using System.Collections.Specialized;

namespace OpenExpressApp.WPF.Controls
{
    /// <summary>
    /// 是否显示业务对象的过滤条件
    /// </summary>
    public interface IChildrenFilter
    {
        /// <summary>
        /// 是否显示业务对象
        /// </summary>
        /// <param name="childModel">被检查的孩子对象</param>
        /// <returns></returns>
        bool CouldShow(object childModel);
    }

    /// <summary>
    /// 树型的列表编辑控件。
    /// 
    /// 只支持主对象为树和普通对象，子对象为普通对象。父对象下只存在一个子对象。列根据对象属性Name来对应
    /// </summary>
    public partial class MultiObjectTreeView : TreeViewBase<BusinessBase>, ISelectableListControl
    {
        private bool _isReadOnly;

        private object _rootPid;

        /// <summary>
        /// 主对象是否为树
        /// </summary>
        private bool _rootIsTree;

        private bool _lazyTreeNodeRelation;

        /// <summary>
        /// 必须为ObservableCollection,这样会根节点会自动更新
        /// </summary>
        private IList _itemsSource;

        /// <summary>
        /// 每个对象对应的节点
        /// </summary>
        private Dictionary<object, TreeListViewItem> _objectItems;

        public MultiObjectTreeView()
        {
            base.Tree = new TreeListView();
            this._rootIsTree = true;
            this._objectItems = new Dictionary<object, TreeListViewItem>();
            this.SetValue(KeyboardNavigation.TabNavigationProperty, KeyboardNavigationMode.Contained);
            this.BindData(null);//默认Pid=null加载树

            //都按懒加载关系处理
            this._lazyTreeNodeRelation = true;
            //如果懒加载关系，则不保留扩展关系
            this.PreserveLayoutOnRefresh = false;
            this.ObserveChildItems = false;
        }

        public Dictionary<object, TreeListViewItem> ObjectItems
        {
            get
            {
                return this._objectItems;
            }
        }

        public bool IsReadOnly
        {
            get
            {
                return this._isReadOnly;
            }
            set
            {
                this._isReadOnly = value;
            }
        }

        public new TreeListView Tree
        {
            get
            {
                return (TreeListView)(base.Tree);
            }
        }

        public IList ItemsSource
        {
            get
            {
                return this._itemsSource;
            }
            set
            {
                this._itemsSource = value;
                this.BindData(null);
            }
        }

        /// <summary>
        /// 返回第一个对象的类型
        /// </summary>
        private Type RootType
        {
            get
            {
                if (this._itemsSource != null && this._itemsSource.Count > 0)
                {
                    return this._itemsSource[0].GetType();
                }
                return null;
            }
        }

        /// <summary>
        /// 根据rootPid绑定this._roots和this.Items
        /// </summary>
        /// <param name="rootPid">
        /// rootPid不指定时,自动构造树;如果这个值不是null，则这个值表示绑定的所有根节点的父id。
        /// </param>
        public void BindData(object rootPid)
        {
            this._rootPid = rootPid;
            this._objectItems.Clear();
            var roots = new ObservableCollection<BusinessBase>();
            this._selectedItems.Clear();

            if (this._itemsSource != null)
            {
                if (this._itemsSource.Count > 0)
                {
                    this._rootIsTree = typeof(ITreeNode).IsAssignableFrom(this.RootType);
                }
                //如果主对象是树，则根据RootPid装载，否则全部装载
                foreach (BusinessBase item in this._itemsSource)
                {
                    if (this._rootIsTree)
                    {
                        ITreeNode node = item as ITreeNode;
                        //rootPid不指定时,自动构造树
                        if (null == rootPid)
                        {
                            bool isroot = this._itemsSource.OfType<ITreeNode>()
                                .All(n => object.Equals(node.Pid, n.Id) == false);
                            if (isroot) roots.Add(item);
                        }
                        else if (object.Equals(rootPid, node.Pid))
                        {
                            roots.Add(item);
                        }
                    }
                    else
                    {
                        roots.Add(item);
                    }
                }
            }

            this.Roots = roots;
        }

        #region 实现父类抽象方法

        /// <summary>
        /// 一个判断子对象是否能显示的过滤条件
        /// </summary>
        private IChildrenFilter _childrenFilter;

        /// <summary>
        /// 一个判断子对象是否能显示的过滤条件
        /// </summary>
        public IChildrenFilter ChildrenFilter
        {
            get
            {
                return this._childrenFilter;
            }
            set
            {
                this._childrenFilter = value;
            }
        }

        public override string GetItemKey(BusinessBase item)
        {
            return GetTreeId(item).ToString();
        }
        public override ICollection<BusinessBase> GetChildItems(BusinessBase parent)
        {
            ICollection<BusinessBase> list = new List<BusinessBase>();

            //检查主对象
            if (this._rootIsTree && (parent.GetType() == RootType))
            {
                foreach (BusinessBase child in this.GetChildrenNodes(parent as ITreeNode))
                {
                    if (this._childrenFilter == null || this._childrenFilter.CouldShow(child))
                    {
                        list.Add(child);
                    }
                }
            }

            //判断子对象
            PropertyInfo treeChildPropertyInfo = ApplicationModel.GetBusinessObjectInfo(parent.GetType()).TreeChildPropertyInfo;
            if (null != treeChildPropertyInfo)
            {
                IList childList = treeChildPropertyInfo.GetValue(parent, null) as IList;
                if (childList.Count > 0)
                {
                    foreach (BusinessBase child in childList)
                    {
                        if (this._childrenFilter == null || this._childrenFilter.CouldShow(child))
                        {
                            list.Add(child);
                        }
                    }
                }
            }

            return list;
        }
        public override BusinessBase GetParentItem(BusinessBase item)
        {
            if (item == null) throw new ArgumentNullException("item");

            //检查主对象
            if (this._rootIsTree &&
                item.GetType() == this.RootType &&
                object.Equals((item as ITreeNode).Pid, this._rootPid) == false)
            {
                return this.GetParentNode(item as ITreeNode) as BusinessBase;
            }
            return null;
        }

        #endregion

        #region 重新实现父类方法

        /// <summary>
        /// for LazyTreeNodeRelation
        /// </summary>
        /// <param name="parent"></param>
        /// <returns></returns>
        protected override bool HasChildItems(BusinessBase parent)
        {
            //检查主对象
            if (this._rootIsTree && parent.GetType() == this.RootType)
            {
                var parentId = GetTreeId(parent);
                foreach (ITreeNode item in this._itemsSource)
                {
                    if (object.Equals(item.Pid, parentId))
                    {
                        return true;
                    }
                }
            }

            //如果没有返回True，再检查子对象
            PropertyInfo treeChildPropertyInfo = ApplicationModel.GetBusinessObjectInfo(parent.GetType()).TreeChildPropertyInfo;
            if (treeChildPropertyInfo != null)
            {
                return (treeChildPropertyInfo.GetValue(parent, null) as IList).Count > 0;
            }

            return false;
        }
        protected override void OnNodeExpanded(TreeViewItem treeNode)
        {
            //检查主对象
            if (this._rootIsTree && treeNode.Header.GetType() == this.RootType)
            {
                if (this._lazyTreeNodeRelation &&
                    treeNode.HasItems &&
                    this.GetChildrenNodes(treeNode.Header as ITreeNode).Count == 0
                    )
                {
                    //Id可能是整形或Guid
                    string curId = (treeNode.Header as ITreeNode).Id.ToString();
                    foreach (ITreeNode item in _itemsSource)
                    {
                        object itemId = item.Pid;
                        if (itemId != null && 
                            object.Equals(itemId, (treeNode.Header as ITreeNode).Id)
                            )
                        {
                            item.ParentNode = treeNode.Header as ITreeNode;
                        }
                    }
                }
            }

            base.OnNodeExpanded(treeNode);
        }
        protected override TreeViewItem CreateTreeViewItem(BusinessBase item)
        {
            var treeListViewItem = new TreeListViewItem();

            #region 赋值属性

            treeListViewItem.TreeView = this;
            Color color = ApplicationModel.GetBusinessObjectInfo(item.GetType()).BackgroundColor;
            if (null != color)
            {
                treeListViewItem.Background = new SolidColorBrush(color);
            }
            //赋值DataContext，否则TreeColumn生成的控件绑定有问题
            treeListViewItem.DataContext = item;

            #endregion

            this._objectItems[GetTreeId(item)] = treeListViewItem;
            return treeListViewItem;
        }
        protected override TreeView CreateTreeView()
        {
            return new TreeListView();
        }
        /// <summary>
        /// override EnsureNodeIsVisible方法,支持多对象的SelectItem的设置
        /// 如果item是ITreeNode则用基类的方法
        /// 否则用自定义的方法
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        protected override TreeViewItem EnsureNodeIsVisible(BusinessBase item)
        {
            if (item is ITreeNode)
            {
                this.EnsureNodeLoaded(item);

                return base.EnsureNodeIsVisible(item);
            }
            else
            {
                var itemKey = GetTreeId(item);

                this.EnsureNodeLoaded(item);

                foreach (var node in this._objectItems.Values)
                {
                    foreach (TreeViewItem child in node.Items)
                    {
                        if (child.Header != null)
                        {
                            var childKey = GetTreeId(child.Header as BusinessBase);
                            if (object.Equals(itemKey, childKey))
                            {
                                return child;
                            }
                        }
                    }
                }

                return null;
            }
        }

        #endregion

        #region 移除节点

        public ObservableCollection<BusinessBase> Roots
        {
            get
            {
                return base.Items as ObservableCollection<BusinessBase>;
            }
            private set
            {
                var oldItems = this.Roots;
                if (oldItems != null)
                {
                    oldItems.CollectionChanged -= Items_CollectionChanged;
                }
                base.Items = value;
                if (value != null)
                {
                    value.CollectionChanged += Items_CollectionChanged;
                }
            }
        }
        /// <summary>
        /// 在界面中移除某个节点
        /// </summary>
        /// <param name="item"></param>
        public void RemoveNode(BusinessBase item)
        {
            TreeListViewItem curItem = null;
            var id = GetTreeId(item);
            if (this._objectItems.TryGetValue(id, out curItem))
            {
                //如果还未扩展建立此节点，则退出
                if (curItem.Parent is TreeViewItem)
                {
                    (curItem.Parent as TreeViewItem).Items.Remove(curItem);
                }
                else
                {
                    //this.Tree.Items.Remove(curItem);

                    this._ignoreItems_CollectionChanged = true;
                    this.Roots.Remove(item);
                    this._ignoreItems_CollectionChanged = false;
                }

                this._objectItems.Remove(id);
            }
        }

        private bool _ignoreItems_CollectionChanged;
        private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (this._ignoreItems_CollectionChanged == false)
            {
                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
                {
                    foreach (BusinessBase item in e.OldItems)
                    {
                        this.RemoveNode(item);
                    }
                }
            }
        }

        #endregion

        #region 展开节点

        /// <summary>
        /// 获取对应对象的节点
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public TreeListViewItem GetItemByData(BusinessBase item)
        {
            TreeListViewItem result = null;
            this._objectItems.TryGetValue(GetTreeId(item), out result);
            return result;
        }
        /// <summary>
        /// 确保某个节点已经加载。
        /// 
        /// 如果当前节点不存在，则表明还未懒加载。
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public void EnsureNodeLoaded(BusinessBase nodeData)
        {
            if (nodeData == null) throw new ArgumentNullException("nodeData");

            var nodeId = GetTreeId(nodeData);
            if (this._objectItems.ContainsKey(nodeId))
            {
                return;
            }

            BusinessBase parentNode = null;

            #region 找到parentNode

            //如果是树节点，直接根据树的关系查找父节点。
            if (nodeData is ITreeNode)
            {
                object parentNodeId = (nodeData as ITreeNode).Pid;
                if (parentNodeId != null)
                {
                    foreach (BusinessBase item in this._itemsSource)
                    {
                        if (object.Equals(GetTreeId(item), parentNodeId))
                        {
                            parentNode = item;
                            break;
                        }
                    }
                }
            }
            //node 不是树节点，则它是个孩子节点
            //获取一个非ITreeNode的对象“nonTreeNode”的ITreeNode父节点
            else
            {
                PropertyInfo treeChildPropertyInfo = ApplicationModel.GetBusinessObjectInfo(this.RootType).TreeChildPropertyInfo;

                foreach (BusinessBase item in this._itemsSource)
                {
                    var list = treeChildPropertyInfo.GetValue(item, null) as IList;
                    if (list != null)
                    {
                        foreach (BusinessBase child in list)
                        {
                            var childId = GetTreeId(child);
                            if (object.Equals(childId, nodeId))
                            {
                                parentNode = item;
                                break;
                            }
                        }
                        if (parentNode != null)
                        {
                            break;
                        }
                    }
                }
            }

            #endregion

            if (parentNode != null)
            {
                //保证父结点也已经加载
                this.EnsureNodeLoaded(parentNode);

                //重新装载子节点
                TreeListViewItem parentTreeViewItem = null;
                if (this._objectItems.TryGetValue(GetTreeId(parentNode), out parentTreeViewItem))
                {
                    this.OnNodeCollapsed(parentTreeViewItem);
                    this.OnNodeExpanded(parentTreeViewItem);
                }
            }
            else
            {
                var items = this.Roots;
                if (items.Count == 0)
                {
                    items.Add(nodeData);
                }
                else if (items.Contains(nodeData) == false)
                {
                    throw new NotImplementedException("根节点中没有nodeData，这种情况暂时没有处理。");
                    //items.Add(nodeData);
                    //this.Roots = items;
                }
            }
        }
        /// <summary>
        /// 展开指定的对象的node
        /// </summary>
        /// <param name="node"></param>
        public void Expand(BusinessBase node)
        {
            this.Expand(node, true);
        }
        /// <summary>
        /// 展开某个节点
        /// </summary>
        /// <param name="node"></param>
        /// <param name="recur">是否递归展开node的子节点</param>
        /// <returns></returns>
        public void Expand(BusinessBase node, bool recur)
        {
            this.EnsureNodeLoaded(node);

            //如果对象不在Items里面，则return
            TreeListViewItem curItem = null;
            if (this._objectItems.TryGetValue(GetTreeId(node), out curItem))
            {
                //重新打开，重新加载子节点。
                this._ignoreSelectedItemSet = true;
                curItem.IsExpanded = false;
                curItem.IsExpanded = true;
                this._ignoreSelectedItemSet = false;

                if (recur)
                {
                    foreach (TreeViewItem item in curItem.Items)
                    {
                        var n = item.Header as BusinessBase;
                        if (this.HasChildItems(n))
                        {
                            this.Expand(n, true);
                        }
                    }
                }
            }
        }
        private bool _ignoreSelectedItemSet;
        public override BusinessBase SelectedItem
        {
            get
            {
                return base.SelectedItem;
            }
            set
            {
                if (this._ignoreSelectedItemSet == false)
                {
                    if (value != null)
                    {
                        this.EnsureNodeLoaded(value);
                    }

                    base.SelectedItem = value;
                }
            }
        }

        #endregion

        #region  选择节点（支持多选）

        private TreeListViewItem _shiftStart;

        private void OnShiftKeyDown()
        {
            if (this._selectedItems.Count > 0)
            {
                var lastOne = this._selectedItems[this._selectedItems.Count - 1];
                this._shiftStart = this._objectItems[GetTreeId(lastOne)];
            }
            else
            {
                this._shiftStart = null;
            }
            //System.Diagnostics.Debug.WriteLine(shiftStart.ToString());
        }

        // a set of all selected items
        private List<BusinessBase> _selectedItems = new List<BusinessBase>();

        public ReadOnlyCollection<BusinessBase> SelectedItems
        {
            get
            {
                return new ReadOnlyCollection<BusinessBase>(this._selectedItems);
            }
        }

        // true only while left ctrl key is pressed
        private bool CtrlPressed
        {
            get
            {
                return System.Windows.Input.Keyboard.IsKeyDown(Key.LeftCtrl);
            }
        }
        private bool ShiftPressed
        {
            get
            {
                return System.Windows.Input.Keyboard.IsKeyDown(Key.LeftShift);
            }
        }

        internal void SelectAll()
        {
            this.ExpandAll();
            this._selectedItems.Clear();
            foreach (BusinessBase item in _itemsSource)
            {
                var treeViewItem = this._objectItems[GetTreeId(item)];

                this.SetItemSelected(treeViewItem);
            }
        }

        //internal void DeselectAll()
        //{
        //    for (int i = selectedItems.Count-1; i >= 0; i--)
        //        Deselect(ObjectTreeViewItems[GetTreeId(selectedItems[i] as BusinessBase)]);
        //    if (null != Tree.SelectedItem )
        //        ChangeSelectedState(Tree.SelectedItem as TreeViewItem);
        //}

        public void DeSelect(TreeViewItem treeViewItem)
        {
            if (treeViewItem == null) throw new ArgumentNullException("treeViewItem");
            this.SetItemDeSelected(treeViewItem);
        }

        protected override void OnSelectedItemChanged(RoutedTreeItemEventArgs<BusinessBase> e)
        {
            //TreeListViewItem treeViewItem = Tree.SelectedItem as TreeListViewItem;
            if (e.NewItem == null)
            {
                return;
            }

            TreeListViewItem treeViewItem = null;
            this._objectItems.TryGetValue(GetTreeId(e.NewItem), out treeViewItem);

            if (treeViewItem != null && this._mouseSelects.ContainsKey(treeViewItem) == false)
            {
                this._mouseSelects.Add(treeViewItem, 0);
            }

            bool multiSelect = this.CtrlPressed;
            this.Select(treeViewItem, multiSelect);

            if (this.ShiftPressed)
            {
                #region Shift多选

                var tiParent = this._shiftStart.Parent as TreeListViewItem;
                var items = tiParent != null ? tiParent.Items : this.Roots.Select(m => this.GetItemByData(m)).ToArray() as IList;

                int startIndex = items.IndexOf(this._shiftStart);
                int endIndex = items.IndexOf(treeViewItem);
                //选择中间的项
                int start = startIndex < endIndex ? startIndex : endIndex;
                int end = startIndex < endIndex ? endIndex : startIndex;
                if (start == -1) return;

                for (int i = start; i <= end; i++)
                {
                    this.Select(items[i] as TreeListViewItem, true);
                }

                #endregion
            }

            base.OnSelectedItemChanged(e);
        }

        /// <summary>
        /// 选中某个item
        /// </summary>
        /// <param name="treeViewItem"></param>
        /// <param name="multiSelect">当前是否支持多选</param>
        private void Select(TreeViewItem treeViewItem, bool multiSelect)
        {
            if (treeViewItem == null)
            {
                return;
            }

            //如果不是多选，则先把原有的所有节点都全部设置为“未选中”状态
            if (multiSelect == false)
            {
                for (int i = this._selectedItems.Count - 1; i >= 0; i--)
                {
                    var item = this._selectedItems[i];
                    var key = GetTreeId(item);

                    TreeListViewItem viewItem = null;
                    if (this._objectItems.TryGetValue(key, out viewItem))
                    {
                        this.SetItemDeSelected(viewItem);
                    }
                    else
                    {
                        this._selectedItems.Remove(item);
                    }
                }

                //var selectedTreeViewItemList = new List<BusinessBase>(this._selectedItems.Count);
                //foreach (var item in this._selectedItems)
                //{
                //    selectedTreeViewItemList.Add(item);
                //}
                //foreach (var item in selectedTreeViewItemList)
                //{
                //    TreeListViewItem viewItem = null;
                //    if (this._objectItems.TryGetValue(GetTreeId(item), out viewItem))
                //    {
                //        this.SetItemDeSelected(viewItem);
                //    }
                //    else
                //    {
                //        throw new NotSupportedException("没有找到对应的Key。");
                //    }
                //}
            }

            this.SetItemSelected(treeViewItem);
        }
        /// <summary>
        /// 设置treeViewItem的颜色为“未选中”状态
        /// </summary>
        /// <param name="treeViewItem"></param>
        private void SetItemDeSelected(TreeViewItem treeViewItem)
        {
            var color = ApplicationModel.GetBusinessObjectInfo(treeViewItem.Header.GetType()).BackgroundColor;
            treeViewItem.Background = new SolidColorBrush(color);
            treeViewItem.Foreground = Brushes.Black;
            this._selectedItems.Remove(treeViewItem.DataContext as BusinessBase); // remove the item from the selected items set
        }
        /// <summary>
        /// 设置treeViewItem的颜色为“选中”状态
        /// </summary>
        /// <param name="treeViewItem"></param>
        private void SetItemSelected(TreeViewItem treeViewItem)
        {
            if (this._selectedItems.Contains(treeViewItem.DataContext as BusinessBase) == false)
            {
                treeViewItem.Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xBA, 0xDD, 0xE9)); // change background and foreground colors
                treeViewItem.Foreground = Brushes.White;
                this._selectedItems.Add(treeViewItem.DataContext as BusinessBase); // add the item to selected items
            }
        }

        # endregion

        #region  支持键盘

        protected override void OnKeyDown(KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Tab:
                    OnTabKeyDown(e);
                    break;

                case Key.Enter:
                    OnEnterKeyDown(e);
                    break;

                case Key.Left:
                case Key.Right:
                case Key.Up:
                case Key.Down:
                    OnArrowKeyDown(e);
                    break;

                case Key.LeftShift:
                case Key.RightShift:
                    OnShiftKeyDown();
                    break;

                case Key.Home:
                case Key.End:
                    OnHomeOrEndKeyDown(e);
                    break;

                case Key.PageUp:
                case Key.PageDown:
                    OnPageUpOrDownKeyDown(e);
                    break;
            }

            if (!e.Handled)
            {
                base.OnKeyDown(e);
            }
        }

        private void OnPageUpOrDownKeyDown(KeyEventArgs e) { }
        private void OnHomeOrEndKeyDown(KeyEventArgs e) { }
        private void OnArrowKeyDown(KeyEventArgs e) { }
        private void OnEnterKeyDown(KeyEventArgs e) { }
        /// <summary>
        /// Called when the tab key is pressed to perform focus navigation.
        /// </summary>
        private void OnTabKeyDown(KeyEventArgs e)
        {
            bool previous = (e.KeyboardDevice.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
            // Start navigation from the current focus to allow moveing focus on other focusable elements inside the cell
            //UIElement startElement = Keyboard.FocusedElement as UIElement;
            UIElement startElement = e.OriginalSource as UIElement;
            if (startElement != null)
            {
                e.Handled = true;
                FocusNavigationDirection direction = previous ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next;
                TraversalRequest request = new TraversalRequest(direction);
                request.Wrapped = true; // Navigate only within treeGrid
                startElement.MoveFocus(request);
            }
        }

        #endregion

        #region  支持拖动多选

        //int 1：向下时选取  -1：向上时选取。 区分方向才知道是否需要deselect
        private Dictionary<TreeListViewItem, int> _mouseSelects = new Dictionary<TreeListViewItem, int>();

        internal Dictionary<TreeListViewItem, int> MouseSelects
        {
            get
            {
                return this._mouseSelects;
            }
        }

        protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
        {
            base.OnPreviewMouseDown(e);

            if (!this.CtrlPressed && (e.LeftButton == MouseButtonState.Pressed))
            {
                if (this._mouseSelects.Count > 1)
                {
                    this._mouseSelects.Clear();
                }
            }
        }

        # endregion

        #region 实现ISelectableListControl接口

        private const int SELECTION_COLUMN_INDEX = 1;

        private bool _selectionEnabled;

        public bool SelectionEnabled
        {
            get
            {
                return this._selectionEnabled;
            }
            set
            {
                if (value)
                {
                    this.EnableSelect();
                }
                else
                {
                    this.DisableSelect();
                }
            }
        }

        private void EnableSelect()
        {
            if (this._selectionEnabled == false)
            {
                var newColumn = new GridViewColumn();
                newColumn.SetValue(Control.NameProperty, BindingPropertyName);  //设置一个名称，以便后面切换编辑样式时设置绑定路径
                //newColumn.SetValue(WPFMeta.BOPropInfoProperty, property);  //存储info,以便后面更新编辑方式使用
                newColumn.Header = "选择";
                newColumn.Width = 50;

                var template = new DataTemplate();
                template.VisualTree = this.GenerateFrameworkElementFactory();
                newColumn.CellTemplate = template;

                this.Tree.Columns.Insert(SELECTION_COLUMN_INDEX, newColumn);

                this._selectionEnabled = true;
            }
        }
        private void DisableSelect()
        {
            if (this._selectionEnabled)
            {
                this.Tree.Columns.RemoveAt(SELECTION_COLUMN_INDEX);

                this._selectionEnabled = false;
            }
        }

        #region 从BooleanTreeColumn类中拷贝过来的方法

        private FrameworkElementFactory GenerateFrameworkElementFactory()
        {
            FrameworkElementFactory border = new FrameworkElementFactory(typeof(Border));
            border.SetValue(Border.BorderThicknessProperty, Tree.BorderThickness);
            border.SetValue(Border.BorderBrushProperty, System.Windows.Media.Brushes.Silver);
            border.SetValue(Border.MarginProperty, OpenExpressApp.Module.WPF.Tree.ElementMargin);

            FrameworkElementFactory element = this.GenerateElementFactoryInBorder();

            border.AppendChild(element);

            return border;
        }
        private FrameworkElementFactory GenerateElementFactoryInBorder()
        {
            FrameworkElementFactory cb = new FrameworkElementFactory(typeof(AlertCheckBox));
            Binding b = new Binding(BindingPropertyName);
            cb.SetBinding(CheckBox.IsCheckedProperty, b);
            cb.SetValue(Border.HorizontalAlignmentProperty, HorizontalAlignment.Center);
            cb.SetValue(Border.VerticalAlignmentProperty, VerticalAlignment.Center);
            return cb;
        }

        #endregion

        private static string BindingPropertyName
        {
            get
            {
                return PropertyConvention.IsSelected;
            }
        }

        #region AlertCheckBox

        /// <summary>
        /// 这个CheckBox在Uncheck时，会弹出提示框。
        /// </summary>
        private class AlertCheckBox : CheckBox
        {
            protected override void OnClick()
            {
                if (this.CanUnCheck())
                {
                    base.OnClick();
                }
            }

            private bool CanUnCheck()
            {
                if (this.IsChecked == true)
                {
                    var result = MessageBox.Show(
                        "将要删除该节点及所有子结点下已经填写的数据，是否继续？",
                        "提示",
                        MessageBoxButton.OKCancel,
                        MessageBoxImage.Warning
                        );
                    if (result != MessageBoxResult.OK)
                    {
                        return false;
                    }
                }
                return true;
            }
        }

        #endregion

        #endregion

        #region 父子关系

        private ITreeNode GetParentNode(ITreeNode node)
        {
            var id = node.Pid;
            return this._itemsSource.OfType<ITreeNode>()
                .FirstOrDefault(n => n.Id.Equals(id));
        }

        private IList<ITreeNode> GetChildrenNodes(ITreeNode node)
        {
            if (this._itemsSource == null) return new ITreeNode[0];

            var id = node.Id;
            return this._itemsSource.OfType<ITreeNode>()
                .Where(n => id.Equals(n.Pid)).ToList();
        }

        #endregion

        #region 静态的辅助方法

        /// <summary>
        /// 获取树节点Id，对于主对象，可能自身树的Id不是对象的Id属性
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static object GetTreeId(BusinessBase model)
        {
            if (model == null) throw new ArgumentNullException("model");

            if (model is ITreeNode)
            {
                return (model as ITreeNode).Id;
            }
            else
            {
                return model.GetPropertyValue(DBConvention.FieldName_Id);
            }
        }

        #endregion
    }
}